package club.ruanx.security.service;

import club.ruanx.acl.entity.SysUser;
import club.ruanx.acl.repository.SysRoleRepository;
import club.ruanx.acl.repository.SysUserRepository;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * @author 阮胜
 * @date 2019/1/6 20:36
 */
@Component
public class AdminDetailServiceImpl implements UserDetailsService {

    public static final String COMMA = ",";
    public static final String ROLE_PREFIX = "ROLE_";
    private final SysUserRepository sysUserRepository;
    private final SysRoleRepository sysRoleRepository;

    public AdminDetailServiceImpl(SysUserRepository sysUserRepository, SysRoleRepository sysRoleRepository) {
        this.sysUserRepository = sysUserRepository;
        this.sysRoleRepository = sysRoleRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<SysUser> sysUserOptional = sysUserRepository.findByUsername(username);
        if (!sysUserOptional.isPresent()) {
            return null;
        }
        SysUser sysUser = sysUserOptional.get();
        Integer[] ids = Stream.of(sysUser.getRoles().split(COMMA)).map(Integer::valueOf).toArray(value -> new Integer[1]);
        String[] roles = sysRoleRepository.findByIdIn(ids)
                .stream()
                .map(u -> ROLE_PREFIX.concat(u.getName()))
                .toArray(roleName -> new String[1]);
        List<GrantedAuthority> authorityList = AuthorityUtils.createAuthorityList(roles);
        return new User(username, sysUser.getPassword(), authorityList);
    }
}
